package client

import (
	"fmt"
	"gin-epg/internal/app/common/util"
	"io"
	"os"
	"path/filepath"
	"strings"
	"time"

	"gin-epg/internal/app/store"
	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/config"
	"github.com/go-git/go-git/v5/plumbing/object"
	"github.com/go-git/go-git/v5/plumbing/transport/http"
)

// SyncXmlGzToGitee 同步多个 XML.gz 文件到 Gitee，每次同步时强制覆盖历史提交记录
func SyncXmlGzToGitee() error {
	url := ""
	userName := ""
	password := ""

	// 获取配置值
	repoUrl, err := util.GetConfigValue("sync.repoUrl")
	repoUserName, err := util.GetConfigValue("sync.repoUserName")
	repoPassword, err := util.GetConfigValue("sync.repoPassword")

	if repoUrl != nil {
		url = repoUrl.(string)
	}
	if repoUserName != nil {
		userName = repoUserName.(string)
	}
	if repoPassword != nil {
		password = repoPassword.(string)
	}
	if url == "" || userName == "" || password == "" {
		return fmt.Errorf("配置错误，请检查 sync.repoUrl、sync.repoUserName 和 sync.repoPassword 是否正确")
	}

	fileNames := []interface{}{
		"e9.xml.gz",
		"e7.xml.gz",
		"e.xml.gz",
	}

	// 创建 gitee同步目录
	tempDirPath := filepath.Join(os.TempDir(), "gitee-sync")
	if err := os.MkdirAll(tempDirPath, os.ModePerm); err != nil {
		return fmt.Errorf("创建临时目录失败: %v", err)
	}
	fmt.Printf("临时目录路径: %s\n", tempDirPath)

	// 创建存储工具下载目录
	tempDir := filepath.Join(os.TempDir(), "xmltvsync")
	if err := os.MkdirAll(tempDir, os.ModePerm); err != nil {
		return fmt.Errorf("创建临时目录失败: %v", err)
	}
	fmt.Printf("存储工具下载目录路径: %s\n", tempDir)

	// 初始化 OSS 存储服务
	ossService := store.GlobalStoreService

	// 初始化或打开本地临时仓库
	repoPath := filepath.Join(tempDirPath, "repo")
	fmt.Printf("Git 仓库路径: %s\n", repoPath)

	// 清理旧的仓库目录（如果存在）
	if _, err := os.Stat(repoPath); !os.IsNotExist(err) {
		if err := os.RemoveAll(repoPath); err != nil {
			return fmt.Errorf("清理旧的仓库目录失败: %v", err)
		}
		fmt.Printf("旧的仓库目录已清理: %s\n", repoPath)
	}

	repo, err := git.PlainOpen(repoPath)
	if err != nil {
		if strings.Contains(err.Error(), "repository does not exist") {
			// 如果仓库不存在，则初始化一个新的仓库
			repo, err = git.PlainInit(repoPath, false)
			if err != nil {
				return fmt.Errorf("初始化 Git 仓库失败: %v", err)
			}
			fmt.Printf("Git 仓库初始化成功: %s\n", repoPath)
		} else {
			return fmt.Errorf("打开 Git 仓库失败: %v", err)
		}
	}

	// 获取工作树
	worktree, err := repo.Worktree()
	if err != nil {
		return fmt.Errorf("获取工作树失败: %v", err)
	}
	fmt.Printf("工作树获取成功\n")

	// 遍历需要同步的文件列表
	for _, fileInterface := range fileNames {
		fileName, ok := fileInterface.(string)
		if !ok {
			fmt.Printf("配置 sync.filesToSync 中包含非字符串项，跳过该项: %v\n", fileInterface)
			continue
		}

		localFilePath := filepath.Join(tempDir, fileName)
		tempFilePath := filepath.Join(repoPath, fileName)

		// 下载文件
		if err := ossService.DownloadToFile(fileName, localFilePath); err != nil {
			fmt.Printf("下载文件 %s 失败: %v\n", fileName, err)
			continue
		}
		fmt.Printf("文件下载成功: %s\n", localFilePath)

		// 复制文件到 Git 仓库目录
		if err := copyFile(localFilePath, tempFilePath); err != nil {
			fmt.Printf("复制文件 %s 失败: %v\n", fileName, err)
			continue
		}
		fmt.Printf("文件复制成功: %s\n", tempFilePath)

		// 添加文件到索引
		if _, err := worktree.Add(fileName); err != nil {
			fmt.Printf("添加文件 %s 到 Git 失败: %v\n", fileName, err)
			continue
		}
		fmt.Printf("文件 %s 添加到索引成功\n", fileName)
	}

	// 获取当前时间并格式化
	currentTime := time.Now().Format("2006-01-02 15:04:05")

	// 提交更改
	commitHash, err := worktree.Commit(fmt.Sprintf("同步 XML.gz 文件 - %s", currentTime), &git.CommitOptions{
		Author: &object.Signature{
			Name:  "sync",
			Email: "sync@example.com",
			When:  time.Now(),
		},
	})
	if err != nil {
		return fmt.Errorf("提交更改失败: %v", err)
	}
	fmt.Printf("提交成功，提交哈希: %s\n", commitHash)

	// 添加远程仓库（如果尚未添加）
	remoteName := "origin"
	if _, err := repo.Remote(remoteName); err != nil {
		if err == git.ErrRemoteNotFound {
			// 添加远程仓库
			_, err := repo.CreateRemote(&config.RemoteConfig{
				Name: remoteName,
				URLs: []string{url},
			})
			if err != nil {
				return fmt.Errorf("添加远程仓库失败: %v", err)
			}
			fmt.Printf("远程仓库添加成功\n")
		} else {
			return fmt.Errorf("检查远程仓库失败: %v", err)
		}
	}

	// 强制推送到远程仓库
	if err := repo.Push(&git.PushOptions{
		RemoteName: remoteName,
		RefSpecs: []config.RefSpec{
			config.RefSpec("refs/heads/master:refs/heads/master"),
		},
		Auth: &http.BasicAuth{
			Username: userName,
			Password: password,
		},
		Force: true,
	}); err != nil {
		return fmt.Errorf("强制推送失败: %v", err)
	}
	fmt.Printf("强制推送成功\n")

	return nil
}

// copyFile 复制文件
func copyFile(src, dst string) error {
	in, err := os.Open(src)
	if err != nil {
		return err
	}
	defer in.Close()

	out, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, in)
	return err
}
